/**
 * ****************************** ICE *******************************
 * ========================================================================
 * Project:  icetalk
 * Package: org.ice4apps.talk 
 * File:  UserSession.java
 * Author: biju
 * Date: Dec 10, 2009
 * Description:
 * ========================================================================
 */
package org.ice4apps.talk.callManager;

import java.util.Vector;

import javax.servlet.sip.SipServlet;
import javax.servlet.sip.SipServletRequest;
import javax.servlet.sip.SipServletResponse;

import org.ice4apps.util.IceLog;
import org.ice4apps.talk.callManager.Features.Postprocess.Postprocess;
import org.ice4apps.talk.callManager.Features.Preprocess.*;
import org.ice4apps.talk.entity.UserSessionType;
import org.ice4apps.talk.entity.UserSessionMessage;

/**
 * @author biju
 * The way state machine is modeled as One Session will have only one Originating and
 * one Terminating Leg
 */
public class UserSession {

	public enum UserSessionState {
		INITIATING,
		CONNECTED,
		TERMINATING,
		HELD,
		SUSPENDED,
		FINAL
	}

	private UserSessionState userSessionState;
	
	private UserSessionType userSessionType;
	
	private UserSessionManager userSessionManager;
	
	private FeatureMapping featureMapping;
	
	private UserSessionMessage termMsg;
	
	private boolean postSessionMessage;
	
	public UserSession (UserSessionManager userSessionManager,
			            UserSessionState userSessionState,
			            UserSessionType messageDestinationType)
	{
		this.userSessionManager = userSessionManager;
		this.userSessionState = userSessionState;
		this.setUserSessionType(messageDestinationType);
		
		featureMapping = new FeatureMapping ();
		
		Preprocess.Register(this, featureMapping);

		// TODO : get the User Features and fill the Feature Mapping Array

		Postprocess.Register(this, featureMapping);
	}
	
	public void processMessage(UserSessionMessage msg){
		Vector<IceTalkFeature> messageArray = featureMapping.getFeatureArray(
				userSessionState.ordinal(), msg.getMessageType().ordinal());

		for (int i=0;i<messageArray.size();i++){
			IceLog.info(this.getClass(), "Iterating .. " + messageArray.get(i).getClass().getCanonicalName());
			messageArray.get(i).processMessage(msg);
		}

		
		if (true == postSessionMessage){
			userSessionManager.postMessage(termMsg);
		}

		postSessionMessage = false;
	}

	/**
	 * @param userSessionState the userSessionState to set
	 */
	public void setUserSessionState(UserSessionState userSessionState) {
		this.userSessionState = userSessionState;
	}

	/**
	 * @return the userSessionState
	 */
	public UserSessionState getUserSessionState() {
		return userSessionState;
	}

	/**
	 * @param userSessionManager the userSessionManager to set
	 */
	public void setUserSessionManager(UserSessionManager userSessionManager) {
		this.userSessionManager = userSessionManager;
	}

	/**
	 * @return the userSessionManager
	 */
	public UserSessionManager getUserSessionManager() {
		return userSessionManager;
	}

	/**
	 * @param termMsg the termMsg to set
	 */
	public void setTermMsg(UserSessionMessage termMsg) {
		this.termMsg = termMsg;
	}

	/**
	 * @return the termMsg
	 */
	public UserSessionMessage getTermMsg() {
		return termMsg;
	}

	/**
	 * @param postSessionMessage the postSessionMessage to set
	 */
	public void setPostMessage(boolean postSessionMessage) {
		this.postSessionMessage = postSessionMessage;
	}

	/**
	 * @param userSessionType the userSessionType to set
	 */
	public void setUserSessionType(UserSessionType userSessionType) {
		this.userSessionType = userSessionType;
	}

	/**
	 * @return the userSessionType
	 */
	public UserSessionType getUserSessionType() {
		return userSessionType;
	}

/*	
	public boolean processServletRequestMessage(UserSessionMessage msg)
	{
		SipServletRequest request = (SipServletRequest)msg.getMessage();

		if (null == origCallLeg)
		{
			if (!(request.getMethod().equals("INVITE")))
			{
				// We expect only new INVITE message at this stage
				// TODO: Add Error
				int errorResponse = SipServletResponse.SC_FORBIDDEN;
				SipServletResponse errorResp = request.createResponse(errorResponse);
				msg.setResponse(errorResp);
			}

			// This the first request for this session.
			// Create Orig And Term Call Legs
			origCallLeg = new CallLeg(this);
			origCallLeg.setCallLegType(CallLeg.CallLegType.ORIGINATING);
			origCallLeg.setProxyCallLeg(false);
			origCallLeg.setCallLegState(CallLeg.CallLegState.RECEIVED_INVITE);
			origCallLeg.setSipServlet((SipServlet)msg.getOriginator());
			
			termCallLeg = new CallLeg(this);
			termCallLeg.setCallLegType(CallLeg.CallLegType.TERMINATING);
			termCallLeg.setProxyCallLeg(true);
			setUserSessionState(UserSessionState.INITIATING);
			
			// Continue with the Servlet processing
			return true;
		}
		return false;
	}

	public boolean createTermInviteAndSend(UserSessionMessage msg)
	{
		return termCallLeg.createInviteAndSend(msg);
	}
*/	
}
